/*
 * Copyright 2014, NuzoweR@Schneefeuer <nuzower@gmail.com>.
 * The Settlers Online - Combat Simulator (tsosim).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef UTILS_H_
#define UTILS_H_

#include <string>
#include <sstream>
#include <list>
#include <cmath>

namespace utils
{

	typedef std::string::size_type Pos_t;

	void trim_string(std::string& str);

	template<typename T>
	inline std::string to_string(T const& item)
	{
		std::stringstream ss;
		ss << item;
		return ss.str();
	}

	template<typename T>
	inline void from_string(std::string const& str, T& item)
	{
		std::stringstream ss( str );
		ss >> item;
	}

	template<>
	inline void from_string<std::string>(std::string const& str, std::string& item)
	{
		item = str;
	}

	template<typename T>
	inline int extract_list_from_string(std::string const& str, std::list<T>& items, char sep=',')
	{
		if(str.empty()) return 0;

		int count=0;

		std::string check_str;

		Pos_t seppos;
		Pos_t start = 0;
		while ( (seppos = str.find_first_of(sep, start)) != std::string::npos )
		{
			check_str = str.substr(start, seppos-start);
			trim_string(check_str);
			if(check_str.empty()) continue;

			T item;
			from_string( check_str, item );
			items.push_back(item);
			count++;
			start = seppos+1;
		}

		check_str = str.substr(start, str.length()-start);
		trim_string(check_str);
		if(check_str.empty()) return 0;
	
		T item;
		from_string( check_str, item );
		items.push_back(item);
		count++;
	
		return count;
	}


	bool extract_path_string(std::string const& str, int start_pos, std::string& path);

	void path_unify_separator(std::string& path, char sep='/');
	bool path_get_dir_file(std::string const& path, std::string& dir, std::string& file);

	bool check_utf8_bom(std::string& line, bool remove_bom);

	/*
	 *  read string and extract front and back part, i.e., front= before ':', back= after ':'
	 */
	bool process_line(std::string const& LINE, int start_pos, std::string& front, std::string& back);

	inline int num_width(double num) {
		if(num==0) 
			return 1;
		else if(num < 0)
			return (int)(log10(num)+1) + 1;
		else 
			return (int)(log10(num)+1);
	}

	bool compare_string_prefix(std::string const& s1, std::string const& s2);

	struct str_less {
		bool operator() (std::string const& s1, std::string const& s2) const {
			return compare_string_prefix(s1,s2);
		}
	};

	int UTF8LEN(std::string const& str);

}

#endif // UTILS_H_
